package _5thread;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

/**
 * @Description:
 * @Author wangzhen
 * @Date 2022-06-18 11:29
 **/

public class LongAdderTest {

    static long value;

    public static synchronized void add(){
        value++;
    }

    public static synchronized long get(){
        return value;
    }



    public static void main(String[] args) throws InterruptedException {

        CountDownLatch countDownLatch1 = new CountDownLatch(1000);

        AtomicLong atomicLong = new AtomicLong(0L);
        CountDownLatch countDownLatch2 = new CountDownLatch(1000);

        LongAdder longAdder = new LongAdder();
        CountDownLatch countDownLatch3 = new CountDownLatch(1000);

        LongAccumulator longAccumulator = new LongAccumulator((x, y) -> x + y, 0);
        CountDownLatch countDownLatch4 = new CountDownLatch(1000);


        //普通同步操作
        long start1 = System.currentTimeMillis();
        for (int i = 1; i <= 1000; i++) {

            new Thread(() -> {

                try {
                    for (int y = 1; y <= 30000; y++) {

                        add();
                    }


                } finally {
                    countDownLatch1.countDown();
                }

            }).start();

        }

        countDownLatch1.await();
        long end1 = System.currentTimeMillis();
        System.out.println("synchronized计算完成,结果为:" + get() + ",耗时:" + (end1 - start1));


        //AtomicCAS操作
        long start2 = System.currentTimeMillis();
        for (int i = 1; i <= 1000; i++) {

            new Thread(() -> {

                try {
                    for (int y = 1; y <= 30000; y++) {

                        atomicLong.getAndAdd(1);
                    }


                } finally {
                    countDownLatch2.countDown();
                }

            }).start();

        }

        countDownLatch2.await();
        long end2 = System.currentTimeMillis();
        System.out.println("AtomicLong计算完成,结果为:" + atomicLong.get() + ",耗时:" + (end2 - start2));


        //LongAdder操作
        long start3 = System.currentTimeMillis();
        for (int i = 1; i <= 1000; i++) {

            new Thread(() -> {

                try {
                    for (int y = 1; y <= 30000; y++) {

                        longAdder.increment();
                    }

                } finally {
                    countDownLatch3.countDown();
                }

            }).start();

        }

        countDownLatch3.await();
        long end3 = System.currentTimeMillis();
        System.out.println("LongAdder计算完成,结果为:" + longAdder.sum() + ",耗时:" + (end3 - start3));


        //longAccumulator操作
        long start4 = System.currentTimeMillis();
        for (int i = 1; i <= 1000; i++) {

            new Thread(() -> {

                try {
                    for (int y = 1; y <= 30000; y++) {

                        longAccumulator.accumulate(1);
                    }

                } finally {
                    countDownLatch4.countDown();
                }

            }).start();
        }

        countDownLatch4.await();
        long end4 = System.currentTimeMillis();
        System.out.println("LongAccumulator计算完成,结果为:" + longAccumulator.get() + ",耗时:" + (end4 - start4));

    }



}
